import * as vscode from 'vscode';
import ts from 'typescript';
import { Project } from 'ts-morph';

export function activate(context: vscode.ExtensionContext) {
	console.log('Congratulations, your extension "codeforfun" is now active!');
	const disposable = vscode.commands.registerCommand('codeforfun.jumpToNgxsState', () => {
		// 获取当前活动的编辑器
		let editor = vscode.window.activeTextEditor;

		if (!editor) {
			vscode.window.showInformationMessage('请先打开一个文件');
			return;
		}

		let workspaceFolders = vscode.workspace.workspaceFolders;
		let rootPath = workspaceFolders?.[0].uri.path;
		// 获取光标位置
		let position = editor.selection.active;
		let document = editor.document;

		let text = document.getText();

		// 解析当前文件的 TypeScript AST
		const sourceFile = ts.createSourceFile(
			document.fileName,
			text,
			ts.ScriptTarget.Latest,
			true
		);

		// 计算光标在文件中的位置
		const cursorPosition = document.offsetAt(position);
		// 获取光标位置的节点
		const node = getNodeAtPosition(sourceFile, cursorPosition);
		// 获取光标位置的文字
		let text1 = node.getText();

		// 扫描全部ts文件
		let project = new Project();
		let sourceFiles = project.addSourceFilesAtPaths([`${rootPath}/**/*.ts`, `!${rootPath}/**/*.d.ts`, `!${rootPath}/**/*spec.ts`]);
		a: for (let file of sourceFiles) {
			const classes = file.getClasses();
			let fileText = file.getText();
			for (let clazz of classes) {
				let classText = clazz.getText();
				if (classText.indexOf('@State') === -1) { continue; }
				if (classText.indexOf('@Action') === -1) { continue; }
				let filePath = file.getFilePath();
				const regex = /@Action\([^)]*\.([^)]+)\)/g;
				let match: RegExpExecArray | null;
				while ((match = regex.exec(fileText)) !== null) {
					if (match[1]) {
						if (text1 === match[1]) {
							let jumpIndex = match.index;
							vscode.workspace.openTextDocument(filePath).then((doc) => {
								vscode.window.showTextDocument(doc).then((editor) => {
									let row = 0;
									let column = 0;
									let currentIndex = 0;
									for (let i = 0; i < editor.document.lineCount; i++) {
										const lineText = editor.document.lineAt(i).text;
										const lineLength = lineText.length;
										if (currentIndex + lineLength >= jumpIndex) {
											row = i;
											column = jumpIndex - currentIndex;
											break;
										}
										currentIndex += lineLength + 1; // +1 是因为换行符
									}
									const position = new vscode.Position(row, column);
									editor.selection = new vscode.Selection(position, position);
									editor.revealRange(new vscode.Range(position, position), vscode.TextEditorRevealType.InCenter);
								});
							});
							break a;
						}
					}
				}

			}
		}
	});
	context.subscriptions.push(disposable);
}

// 工具函数：获取光标位置的节点
function getNodeAtPosition(sourceFile: ts.SourceFile, position: number): ts.Node {
	let foundNode: ts.Node | undefined;

	function find(node: ts.Node) {
		if (position >= node.getStart() && position < node.getEnd()) {
			foundNode = node;
			ts.forEachChild(node, find);
		}
	}

	find(sourceFile);
	return foundNode!;
}

export function deactivate() { }
